繼續來探討Active Record相關的面試題,Active Record除了昨天提到的migration外,還有另外一個功能是有callback。
What are callbacks?
什麼是Callback?
Callback是在物件生命週期的特定時機執行一些程式碼,例如在物件創造前(before_create)、存取後(after_save),刪掉之後(after_destroy)等等。
要是我們總是在物件生命週期的某個時間點,想要執行某些事情,就可以利用callback,例如:當創造使用者帳號的時候,將使用者的email改小寫英文字母,有點像是在說:「嘿 Active Record,當你創造出一個user物件後跟我說一聲唷,這樣我就可以在其他事情發生前執行這個方法。」
要使用callback,要像以下這種寫法
class User < ApplicationRecord
validates :login, :email, presence: true
before_validation :ensure_login_has_a_value
private
def ensure_login_has_a_value
if login.nil?
self.login = email unless email.blank?
end
end
end
在驗證前before_validation
,想要先執行ensure_login_has_a_value
這個方法來確定,login是有值。
如果程式碼短到一行可以寫完,也可以用block的方式來寫
class User < ApplicationRecord
validates :login, :email, presence: true
before_create do
self.name = login.capitalize if name.blank?
end
end
習慣上會將這些方法寫private method,以符合物件封裝的概念。
舉物件被創造時,有以下的callback可以使用,按照順序排列
before與after比較好理解,around開頭的就比較難懂一點,通常是在會寫一個yield有關的方法在原本的action裡,不太常見所以先跳過不看。
更新物件時的callback
可以看到與創造時特別像,值得注意的是after_save這個方法在創造與更新時都有,不過都是在特定的callback之後才會觸發(after_create/after_update)。
刪除物件時的callback
callback可以透過model之間的關聯運作,例如使用者有很多文章,當使用者被刪除的時候,屬於使用者的文章也應該被刪除,我們就試著藉由Aticle
與User
的關聯性,來對User
model加上after_destroy
方法。
class User < ApplicationRecord
has_many :articles, dependent: :destroy
end
class Article < ApplicationRecord
after_destroy :log_destroy_action
def log_destroy_action
puts 'Article destroyed'
end
end
>> user = User.first
=> #<User id: 1>
>> user.articles.create!
=> #<Article id: 1, user_id: 1>
>> user.destroy
Article destroyed
=> #<User id: 1>
關鍵是在User
後面有dependent: :destroy
這個關聯性,當user被刪除,使用者的文章也會被刪除,所以連動了article的destroy,而觸發了after_destroy這個callback。
也可以搭配if
unless
等等,寫出像下面這樣的程式碼
class Order < ApplicationRecord
before_save :normalize_card_number, if: :paid_with_card?
end
當if後面這個方法回傳true的時候,才會執行前面這個callback。
callback這個名詞本身有點誤導,之後幾天再來多挑幾題相關的,更了解callback的應用時機吧!
Callback是在物件生命週期的特定時機執行一些程式碼,在物件創造、更新、刪除的前後有很多callback可以使用,例如在物件創造前(before_create)、存取後(after_save),刪掉之後(after_destroy)等等。
如果我們總是在物件生命週期的某個時間點,想要執行某些事情,就可以利用callback來完成。
1.Rubyguide-ActiveRecord Callbacks
2.Ruby on Rail- ACTIVE RECORD CALLBACKS
3.為你自己學 Ruby on Rails-Model 驗證及回呼